package com.hcjy.util;

import com.hcjy.common.AppProperties;
import com.hcjy.common.exception.CommonException;
import com.hcjy.entity.bo.SmsCodeBo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author Guqier
 * @version 1.0
 * @date 2025/6/7 16:36
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SmsUtils {

    private final RedisUtils redisUtils;

    public final Integer CODE_LENGTH = 6; // 验证码长度

    /**
     * 发送短信验证码
     * @param phone 手机号
     * @return 验证码ID
     */
    public String sendSmsCode(String phone){
        // TODO: 调用短信服务发送验证码，现在仅作模拟

        // 检查一分钟是否发送过验证码
        SmsCodeBo existingCode = redisUtils.getCacheObject(AppProperties.Cache.VERIFY_CODE_PHONE.getKey(phone));
        if (existingCode != null && existingCode.getSendTime().isAfter(LocalDateTime.now().minusMinutes(1))) {
            throw new CommonException("验证码发送过于频繁，请稍后再试！");
        }

        // 生成验证码并存入缓存
        String code = generateCode(CODE_LENGTH);
        String codeId = UUID.randomUUID().toString();
        redisUtils.setCacheObject(
                AppProperties.Cache.VERIFY_CODE_PHONE.getKey(phone),
                new SmsCodeBo().setCode(code).setPhone(phone).setCodeId(codeId).setSendTime(LocalDateTime.now()),
                10,
                TimeUnit.MINUTES);

        // 模拟发送短信
        log.info("Sending SMS code: {} to phone: {}", code, phone);
        return codeId;
    }

    /**
     * 生成随机验证码
     * @param length 验证码长度
     * @return 生成的验证码字符串
     */
    private String generateCode(Integer length) {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int digit = (int) (Math.random() * 10); // 生成0-9的随机数字
            code.append(digit);
        }
        return code.toString();
    }

    /**
     * 验证短信验证码
     * @param code 验证码
     * @param phone 手机号
     * @return 是否验证成功
     */
    public boolean verifyCode(String code, String phone, String codeId) {
        SmsCodeBo smsCodeBo = redisUtils.getCacheObject(AppProperties.Cache.VERIFY_CODE_PHONE.getKey(phone));
        // 检查验证码是否存在
        if (smsCodeBo == null) {
            return false;
        }
        // 检查验证码ID是否匹配
        if (!smsCodeBo.getCodeId().equals(codeId)) {
            return false;
        }
        // 检查手机号和验证码是否匹配
        if (!smsCodeBo.getPhone().equals(phone)) {
            return false;
        }
        return smsCodeBo.getCode().equals(code);
    }
}
